<!--
 统一配置popup弹框
 @Author: mosowe
 @Date:2022-12-29 16:44:21
-->

<template>
  <uni-popup
    ref="ZoPopupRef"
    :type="props.simple ? 'center' : props.type"
    :is-mask-click="props.isMaskClick">
    <template v-if="!props.simple">
      <view
        :class="['popup-content', props.type]"
        :style="{ 'background-color': props.bgColor }">
        <!-- 右上角关闭按钮 -->
        <view
          class="popup-close"
          v-if="props.showClose">
          <text
            class="zoicon zo-circle-close"
            @click="iconClose"></text>
        </view>
        <!-- 标题 -->
        <view
          :class="['popup-title', props.titleAlign, props.showClose ? 'has-close' : '']"
          v-if="props.title">
          {{ props.title }}
        </view>
        <!-- 内容 -->
        <view class="popup-body">
          <slot></slot>
        </view>
        <!-- 底部按钮 -->
        <template v-if="!props.hideFooter">
          <slot name="footer">
            <view :class="['popup-footer', props.footerType]">
              <view
                :class="['footer-btn', 'cancel', props.btnRadius ? 'radio' : '', props.cancelClass]"
                :style="`${props.cancelColor ? 'color:' + props.cancelColor + ';' : ''}${
                  props.cancelBgColor ? 'background:' + props.cancelBgColor : ''
                }`"
                v-if="!props.hideCancel"
                @click="cancel">
                {{ props.cancelText }}
              </view>
              <view
                :class="['footer-btn', 'ok', props.btnRadius ? 'radio' : '', props.okClass]"
                :style="`${props.okColor ? 'color:' + props.okColor + ';' : ''}${
                  props.okBgColor ? 'background:' + props.okBgColor : ''
                }`"
                @click="confirm">
                {{ props.okText }}
              </view>
            </view>
          </slot>
        </template>
        <slot name="bottom"></slot>
        <view
          class="popup-iphone-x-bottom"
          v-if="props.type === 'bottom'"></view>
      </view>
    </template>
    <template v-else>
      <view class="popup-simple-content">
        <slot></slot>
        <!-- 底部关闭按钮 -->
        <view
          class="popup-simple-close"
          v-if="!props.hideSimpleClose">
          <text
            class="zoicon zo-circle-close"
            @click="iconClose"></text>
        </view>
      </view>
    </template>
  </uni-popup>
</template>

<script setup lang="ts">
/* 
  父组件通过ref调用open()方法来打开弹框
    slot: 
      default:内容区插槽
      footer：底部按钮区插槽
      bottom：按钮区下面的插槽
    emits：
      confirm() 确定按钮点击
      cancel()  取消按钮点击
      close()   右上角关闭图标按钮点击
  */

import { ref } from 'vue';

// props
interface PropsType {
  title?: string; // 弹框标题
  titleAlign?: 'center' | 'left'; // 标题对其方式
  okText?: string; // 确定按钮文案
  okColor?: string; // 确定按钮颜色
  okBgColor?: string; // 确定按钮背景色
  okClass?: string; // 确定按钮样式名
  closeOnOk?: boolean; // 点击确定按钮是否直接关闭弹框
  cancelText?: string; // 取消按钮文案
  cancelColor?: string; // 取消按钮颜色
  cancelBgColor?: string; // 取消按钮背景色
  cancelClass?: string; //取消按钮样式名
  footerType?: undefined | 'button'; // 按钮类型
  hideCancel?: boolean; // 是否隐藏取消按钮
  showClose?: boolean; // 是否显示右上角关闭按钮
  closeOnIcon?: boolean; // 点击右上角关闭按钮图标是否直接关闭
  type?: 'center' | 'bottom'; // 弹出框位置
  bgColor?: string; // 内容背景色
  isMaskClick?: boolean; // 点击蒙层是否关闭弹框
  btnRadius?: boolean; // 按钮椭圆
  hideFooter?: boolean; // 隐藏底部按钮区
  simple?: boolean; // 简洁模式，不带背景色，无取消确认按钮，以上props除isMaskClick外均失效，默认底部一个关闭icon，可通过hideSimpleClose关闭,
  hideSimpleClose?: boolean; // 简洁模式-隐藏关闭按钮，处于弹框内容底部的，默认false
}
const props = withDefaults(defineProps<PropsType>(), {
  titleAlign: 'center',
  okText: '确定',
  cancelText: '取消',
  type: 'center',
  hideCancel: false,
  bgColor: '#ffffff',
  showClose: false,
  closeOnOk: true,
  closeOnIcon: true,
  btnRadius: false,
  simple: false,
  hideSimpleClose: false
});

// emits
interface EmitsType {
  (e: 'confirm'): void;
  (e: 'cancel'): void;
  (e: 'close'): void;
}
const emits = defineEmits<EmitsType>();

// uni-popup的ref
const ZoPopupRef = ref<POPUP_TYPE | null>(null);

// 打开弹框
const open = () => {
  ZoPopupRef.value?.open();
};
// 关闭弹框
const close = () => {
  ZoPopupRef.value?.close();
};
// 点击右上角关闭 按钮关闭
const iconClose = () => {
  emits('close');
  if (props?.closeOnIcon) {
    close();
  }
};

// 点击确定按钮
const confirm = () => {
  emits('confirm');
  if (props.closeOnOk) {
    close();
  }
};
// 点击取消按钮
const cancel = () => {
  emits('cancel');
  close();
};

// 对外暴露方法
defineExpose({
  open,
  close
});
</script>

<style lang="scss">
.popup-content {
  max-width: 630rpx;
  min-width: 580rpx;
  box-sizing: border-box;
  border-radius: 40rpx;
  .popup-close {
    text-align: right;
    padding: 30rpx 30rpx 0 0;
    margin-bottom: -30rpx;
    color: #999999;
    .zo-circle-close {
      font-size: 40rpx;
    }
  }
  .popup-title {
    text-align: center;
    font-size: #333333;
    padding: 40rpx 40rpx 0 40rpx;
    font-size: 36rpx;
    line-height: 40rpx;
    font-weight: bold;
    &.left {
      text-align: left;
    }
    &.has-close {
      margin-top: -70rpx;
    }
  }
  .popup-body {
    padding: 40rpx;
  }
  .popup-footer {
    display: flex;
    border-top: 1rpx solid rgba(0, 0, 0, 0.1);
    align-items: center;
    justify-content: center;
    .footer-btn {
      flex: 1;
      text-align: center;
      line-height: 100rpx;
      font-size: 34rpx;
      max-width: 670rpx;
      &:nth-child(2) {
        border-left: 1rpx solid rgba(0, 0, 0, 0.1);
      }
      &.cancel {
        color: #333333;
      }
      &.ok {
        color: #6cceae;
      }
      &.radio {
        border-radius: 100rpx !important;
      }
    }
    &.button {
      border: none;
      padding: 0 40rpx 40rpx 40rpx;
      .footer-btn {
        width: 248rpx;
        height: 88rpx;
        border-radius: 20rpx;
        line-height: 88rpx;
        font-size: 32rpx;
        &.cancel {
          background-color: #f7f7f7;
          color: #6cceae;
        }
        &.ok {
          background: #6cceae;
          color: #fff;
        }
        &:nth-child(2) {
          margin-left: 30rpx;
          border-left: none;
        }
      }
    }
  }
  &.bottom {
    border-radius: 40rpx 40rpx 0 0;
    max-width: 100vw;
    transform: translateY(env(safe-area-inset-bottom));
    transform: translateY(constant(safe-area-inset-bottom));
  }
  .popup-iphone-x-bottom {
    padding-bottom: env(safe-area-inset-bottom);
    padding-bottom: constant(safe-area-inset-bottom);
  }
}
.popup-simple-content {
  .popup-simple-close {
    text-align: center;
    margin-top: 45rpx;
    .zoicon {
      font-size: 60rpx;
      color: #ffffff;
      line-height: 60rpx;
    }
  }
}
</style>
